package com.leyou.trade.service.impl;

import com.leyou.common.exceptions.LyException;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.enums.OrderStatus;
import com.leyou.trade.service.OrderService;
import com.leyou.trade.service.PayService;
import com.leyou.trade.utils.PayHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * @author 虎哥
 */
@Service
public class PayServiceImpl implements PayService {

    @Autowired
    private PayHelper payHelper;

    @Autowired
    private OrderService orderService;

    @Override
    public String getPayUrl(Long orderId) {
        // 1.根据id查询订单
        Order order = orderService.getById(orderId);
        if (order == null) {
            throw new LyException(400, "订单id错误！");
        }
        // 2.判断订单支付状态
        Integer status = order.getStatus();
        if (!OrderStatus.INIT.getValue().equals(status)) {
            // 订单已经支付或关闭
            throw new LyException(400, "订单已经支付或关闭");
        }
        // 3.获取订单金额
        Long actualFee = order.getActualFee();

        // 4.获取商品描述
        String desc = "乐优商城-订单商品";
        return payHelper.getPayUrl(orderId, actualFee, desc);
    }

    @Override
    @Transactional
    public void handleWxNotify(Map<String, String> data) {
        // 1.基本校验
        // 1.1.通信标示校验
        payHelper.checkReturnCode(data);
        // 1.2.业务标示校验
        payHelper.checkResultCode(data);
        // 1.3.签名校验
        payHelper.checkSignature(data);

        // 2.订单金额校验
        // 2.1.获取订单id和支付金额
        String totalFeeStr = data.get("total_fee");
        String outTradeNo = data.get("out_trade_no");
        if (StringUtils.isBlank(totalFeeStr) || StringUtils.isBlank(outTradeNo)) {
            // 数据有误
            throw new LyException(400, "请求参数有误，订单金额或订单编号为空！");
        }
        // 2.2.查询数据库订单
        Long orderId = null;
        try {
            orderId = Long.valueOf(outTradeNo);
        } catch (NumberFormatException e) {
            throw new LyException(400, "订单id格式错误");
        }
        Order order = orderService.getById(orderId);
        if (order == null) {
            // 订单不存在
            throw new LyException(400, "订单不存在");
        }
        // 2.3.比较金额
        String actualFee = order.getActualFee().toString();
        if (!actualFee.equals(totalFeeStr)) {
            // 金额不一致
            throw new LyException(400, "订单金额不一致，再捣乱就报警了！");
        }

        // 3.幂等校验
        if (!Objects.equals(order.getStatus(), OrderStatus.INIT.getValue())) {
            // 订单已经支付或关闭，无需再次处理
            return;
        }

        // 4.更新订单状态，从未支付改为已支付
        // update tb_order set status = 2, pay_time = NOW() where order_id = 1231 AND status = 1
        orderService.update().set("status", OrderStatus.PAY_UP.getValue())
                .set("pay_time", new Date())
                .eq("order_id", orderId)
                .eq("status", OrderStatus.INIT.getValue())
                .update();
    }
}
